﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace Objects
{
    public class Texthost : INotifyPropertyChanged, ICloneable
    {
        private object _DataContext;
        /// <summary>
        /// Контекст данных
        /// </summary>        
        public object DataContext
        {
            get { return _DataContext; }
            set { _DataContext = value; }
        }

        public bool IsArguments
        {
            get { return (_Arguments != null && _Arguments.Length > 0) || _LazyArguments != null; }
        }
        private Func<Texthost, IEnumerable<object>> _LazyArguments;
        /// <summary>
        /// Отложенное получение аргументов
        /// </summary>        
        public Func<Texthost, IEnumerable<object>> LazyArguments
        {
            get { return _LazyArguments; }
            set { _LazyArguments = value; }
        }

        public XElement[] LazyXml;

        private object[] _Arguments;
        /// <summary>
        /// 
        /// </summary>
        public object[] Arguments
        {
            get
            {
                if (_Arguments == null && LazyArguments != null)
                    return LazyArguments(this).ToArray();
                else
                    return _Arguments;
            }
            set
            {
                _Arguments = value;
            }
        }
        private string _Format;
        /// <summary>
        /// Формат строка
        /// </summary>
        public string Format
        {
            get
            {
                return _Format;
            }
            set
            {
                _Format = value;
            }
        }

        protected readonly static Regex FormatMatch = new Regex(@"[\{]{1}[0-9]{1,}[\:\}]{1}", RegexOptions.Compiled);

        /// <summary>
        /// Отформатированная строка
        /// </summary>
        public string Text
        {
            get
            {
                if (IsArguments && FormatMatch.IsMatch(Format))
                    return Format.goFormat(Arguments);
                else
                    return Format;
            }
        }

        public Texthost SetContext(object context)
        {
            DataContext = context;
            return this;
        }

        #region Члены INotifyPropertyChanged

        private void OnPropertyChanged(string PropName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(PropName));
        }
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            Texthost res = new Texthost();
            res._Arguments = _Arguments;
            if (LazyXml != null)
                res.LazyXml = (XElement[])LazyXml.Clone();
            res._Format = _Format;
            res._LazyArguments = _LazyArguments;
            return res;
        }

        #endregion

        public override string ToString()
        {
            return Text;
        }
    }
}
